package MobileCommServer;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;

/**
 * <pre>
 * @Package : MobileCommServer
 * @File    : ClientThread.java
 * <pre>
 *
 * @Author  : 차재우
 * @Date    : 2013. 7. 24.
 * @Version :
 */
class ClientThread implements Runnable {
	private Socket socket = null;
	private int key = 0;

	private DataInputStream in = null;
	private DataOutputStream out = null;
	private BufferedReader br = null;
	
	private SerialQueue sendQueue = null; 
	
	private HashMap<Integer, ClientThread> clients = null;

	/**
	 * <pre>
	 * @Comment : 생성자
	 * <pre>
	 *
	 * @param server
	 */
	public ClientThread(MobileCommServer server) {
		this.socket = server.getSocket();
		this.clients = server.getClients();
		this.key = this.socket.hashCode();
		this.sendQueue = server.getSendQueue();

		try {
			SetCommStream();
			SetSocketTimeout();
		} catch (Exception e) {
			e.printStackTrace();
			try {
				ClientExit();
			} catch (IOException ie) {
				e.printStackTrace();
			}
		}
		
		clients.put(key, this);
	}
	
	/**
	 * <pre>
	 * @Comment : 소켓 통신 스트림 생성
	 * <pre>
	 *
	 * @Method  : SetCommStream
	 * @throws IOException
	 */
	private void SetCommStream() throws IOException {
		in = new DataInputStream(socket.getInputStream());
		out = new DataOutputStream(socket.getOutputStream());
		br = new BufferedReader(new InputStreamReader(in));
	}
	
	
	/**
	 * <pre>
	 * @Comment : 소켓 타임아웃 
	 * <pre>
	 *
	 * @Method  : SetSocketTimeout
	 * @throws SocketException
	 */
	private void SetSocketTimeout() throws SocketException {
		this.socket.setSoTimeout(5 * 1000);
	}

	/**
	 * <pre>
	 * @Comment : 소켓 종료
	 * <pre>
	 *
	 * @Method  : ClientExit
	 * @throws IOException
	 */
	private void ClientExit() throws IOException
	{
		clients.remove(key);
		
		in.close();
		out.close();
		socket.close();
		
		System.out.println("Thread key value : " + key);
		System.out.println(socket.getInetAddress() + " Disconnected.");
		System.out.println("The number of clients connected ---> " + clients.size());
		System.out.println("=================================================================================\n");
	}

	/**
	 * <pre>
	 * @Comment : 스레드 시작
	 * <pre>
	 *
	 * @Method  : run
	 */
	public void run() {
		System.out.println("The number of clients connected ---> " + clients.size());

		while (in != null) {
			try {
				String recvData = br.readLine();
				if(recvData == null)
					continue;
				System.out.println("Receive data : " + recvData);
				
				byte[] serialPacket = SerialPacket.MakeSerialPacket(recvData.getBytes(), this.key);

				sendQueue.Push(serialPacket);

				System.out.println("Send queue size : " + sendQueue.GetQueueSize());
				System.out.println("=================================================================================\n");
			} catch (IOException ie) {
				System.out.println("socket timeout~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
				break;
			} catch (Exception e) {
				e.printStackTrace();
				break;
			}
		}

		try {
			ClientExit();
		} catch (IOException ie) {
			ie.printStackTrace();
		}
	}

	/**
	 * @return the out
	 */
	public DataOutputStream getOut() {
		return out;
	}
}
